package com.xiguaji.tiktok.v1.user.controller;

import com.xiguaji.boot.toolkit.HttpUtil;
import com.xiguaji.tiktok.config.Config;
import com.xiguaji.tiktok.config.exception.ParamsException;
import com.xiguaji.tiktok.utils.Ret;
import com.xiguaji.tiktok.v1.BaseController;
import com.xiguaji.tiktok.v1.common.model.DicAds;
import com.xiguaji.tiktok.v1.common.service.CommonService;
import com.xiguaji.tiktok.v1.product.service.ProductService;
import com.xiguaji.tiktok.v1.user.dto.AdsRecord;
import com.xiguaji.tiktok.v1.user.dto.GoogleUserReceive;
import com.xiguaji.tiktok.v1.user.dto.UserRegister;
import com.xiguaji.tiktok.v1.user.dto.WebConfigReturn;
import com.xiguaji.tiktok.v1.user.log.Operation;
import com.xiguaji.tiktok.v1.user.model.User;
import com.xiguaji.tiktok.v1.user.model.VerityCode;
import com.xiguaji.tiktok.v1.user.service.UserService;
import com.xiguaji.tiktok.v1.user.service.VerityCodeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.PostConstruct;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.validation.Valid;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.Random;
import java.util.concurrent.TimeUnit;


@Api(value = "用户认证",tags = {"用户认证"})
@RestController
@Slf4j
public class ValidateController extends BaseController {

    @Autowired
    private UserService userService;
    @Autowired
    private User.UserRegisterMapper userMapper;
    @Value("${spring.mail.username}")
    private String fromEmail;

    @Autowired
    JavaMailSender javaMailSender;

    @Value("${token.id.expiration}")
    long tokenIdExpiration;

    @Autowired
    RedisTemplate<String,String> redisTemplate;

    @Autowired
    CommonService commonService;

    @Autowired
    private VerityCodeService verityCodeService;

    @Autowired
    Config config;

    @Autowired
    ProductService productService;

    WebConfigReturn webConfigReturn;

    private final String facebookUrl = "https://graph.facebook.com/v9.0/me?fields=id,name,location,email,first_name,last_name&access_token=";

    @PostConstruct
    public void postConstruct(){
        webConfigReturn = new WebConfigReturn();
        webConfigReturn.setGoogleClientId(config.getGoogleClientId());
    }



    String codeHtml = "<div style=\"width:100%;max-width: 440px; padding: 0 20px;\">\n" +
            "    <div style=\"max-width:100%;background-color: #f1f1f1; padding: 20px 16px; font-weight: bold;font-size: 20px;color: rgb(22,24, 35)\"><font></font>\n" +
            "      Verification Code<font></font>\n" +
            "    </div>\n" +
            "    <div style=\"max-width:100%;background-color: #f8f8f8; padding: 24px 16px;font-size: 17px;color: rgba(22,24, 35, 0.75);line-height: 20px;\">\n" +
            "      <p style=\"margin-bottom:20px;\">To verify your account, enter this code in Gugee Data sign-up page:</p>\n" +
            "      <p style=\"margin-bottom:20px;color: rgb(22,24,35);font-weight: bold;\">{validateCode}</p>\n" +
            "      <p style=\"margin-bottom:20px;\">Verification codes expire after 24 hours.</p>\n" +
            "      <p style=\"margin-bottom:20px;\">If you didn't request this code, you can ignore this message.</p><font></font>\n" +
            "<font></font>\n" +
            "      <p>Gugee Data Support Team</p></div></div>";

    @ApiOperation(value = "注册",notes = "注册")
    @RequestMapping(value = "register",method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public String register(@Valid @RequestBody UserRegister register, String chl){

        if(null != userService.getUserByEamil(register.getEmail())){
            // return Ret.err("该邮箱已注册！");
            return Ret.err("This email has been registered");
        }

        if(!verityCodeService.validate(register.getEmail(),register.getCode())){
            // return Ret.err("验证码错误");
            return Ret.err("Verification code is invalid");
        }

        User u = userMapper.mapper(register);
        u.setActivation(true);
        u.setCreateBy("UserController->register");
        u.setUpdateBy("UserController->register");
        userService.saveUser(u);
        String token = userService.login(u);
        setLoginCookie(token);
        saveUserAds(chl,u.getId());
        return Ret.success("register success!");
    }

    @ApiOperation(value = "谷歌登入",notes = "{\"email\":\"466636298@qq.com\",\"password\":\"321654\"}")
    @ApiResponses(value = {
            @ApiResponse(code = 200,message = "{\n\"Msg\":\"登入成功！\",\n\"Data\":\"43O9y-71M\",\n\"Code\":200\n}")
    })
    @RequestMapping(value="google/login",method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @Operation("谷歌登入")
    public String googleLogin(@RequestBody String body, String chl) throws ParamsException {
        GoogleUserReceive googleUserReceive = getParam(GoogleUserReceive.class, body);
        User user = userService.getUserByEamil(googleUserReceive.getEmail());
        if(null == user){
            user = new User();
            user.setFirstName(googleUserReceive.getFirstName());
            user.setLastName(googleUserReceive.getLastName());
            user.setAvatar(googleUserReceive.getAvatar());
            user.setEmail(googleUserReceive.getEmail());
            user.setCreateBy("from google");
            user.setUpdateBy("google login");
            user.setActivation(true);
            user.setSource(2);
            user.setParentId(0L);
            userService.saveUser(user);
            saveUserAds(chl,user.getId());
        }
        return loginBack(user);
    }

    @ApiOperation(value = "facebook登入",notes = "facebook登入")
    @RequestMapping(value="fb/login",method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public String facebookOAuth(@RequestBody String body, String chl) throws ParamsException {
        GoogleUserReceive googleUserReceive = getParam(GoogleUserReceive.class, body);
        User user = userService.getUserByEamil(googleUserReceive.getEmail());
        if(null == user){
            user = new User();
            user.setFirstName(googleUserReceive.getFirstName());
            user.setLastName(googleUserReceive.getLastName());
            user.setAvatar(googleUserReceive.getAvatar());
            user.setEmail(googleUserReceive.getEmail());
            user.setCreateBy("from facebook");
            user.setUpdateBy("facebook login");
            user.setActivation(true);
            user.setSource(3);
            user.setParentId(0L);
            userService.saveUser(user);
            saveUserAds(chl,user.getId());
        }

        return loginBack(user);
    }

    @RequestMapping(value = "/config",method = RequestMethod.GET)
    @Operation(value = "获取WEB上的配置")
    public String getWebConfigure(){
        return Ret.success("success!",webConfigReturn);
    }

    @RequestMapping(value = "count/visit/register",method = RequestMethod.GET)
    @Operation(value = "注册访问")
    public String countVisitRegister(){
        return Ret.success("success!");
    }

    @RequestMapping(value = "testPage",method = RequestMethod.GET)
    public ModelAndView testPage(ModelAndView model){
        model.setViewName("paypal");
        return model;
    }

    @ApiOperation(value = "登入",notes = "{\"email\":\"466636298@qq.com\",\"password\":\"321654\"}")
    @ApiResponses(value = {
            @ApiResponse(code = 200,message = "{\n\"Msg\":\"登入成功！\",\n\"Data\":\"43O9y-71M\",\n\"Code\":200\n}")
    })
    @RequestMapping(value="login",method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @Operation("系统登入")
    public String login(@RequestBody String body) throws ParamsException {
        String email = getParam(body,"email");
        String password = getParam(body,"password");
        User user = userService.getUserByEmailAndPassword(email,password);

        if(null == user){
            return Ret.err("The mailbox or password is wrong, please re-enter");
        }

        if(!user.getActivation()){
            return Ret.err("Please active account");
        }
        return loginBack(user);
    }

    // 登入成功后的设置
    private String loginBack(User user){
        String token = userService.login(user);
        setLoginCookie(token);
        String tokenId = encrypt(user.getId());
        userService.redisTemplate.opsForValue().set(tokenId,token,tokenIdExpiration, TimeUnit.SECONDS);
        user.setLastLoginTime(System.currentTimeMillis()/1000);
        userService.saveUser(user);
        // redisTemplate.opsForValue().set(tokenId,token,tokenIdExpiration);
        return Ret.success("login success",tokenId);
    }
    @ApiOperation(value = "登出")
    @RequestMapping(value="login/out",method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    public String loginOut(){
        User user = getUser();
        if(null != user){
            redisTemplate.delete(String.valueOf(user.getId()));
        }

        setLoginCookie("");
        return Ret.success("login out success");
    }


    @ApiOperation(value="认证")
    @RequestMapping(value = "verify/subuser",method = RequestMethod.GET)
    public void validateSubUser(String data) throws IOException, ParamsException {
        String email = getParam(String.class, URLDecoder.decode(data,"UTF-8"),"email");
        User user = userService.getUserByEamil(email);

        if(null == user){
            HttpUtil.getResponse().sendRedirect("https://tk.gugeedata.com/?verification=0");
        }
        user.setActivation(true);
        user.setUpdateBy("verify success");
        userService.saveUser(user);
        HttpUtil.getResponse().sendRedirect("https://tk.gugeedata.com/?verification=1");
    }

    /*@ApiOperation(value = "验证token是否可用",notes = "正确登入返回token")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token",value = "token",required = true,paramType = "query",dataType = "String"),
    })
    @RequestMapping(value="token/validate",method = RequestMethod.POST)
    public String validate(String token){
        if(userService.validaToken(token)){
            return Ret.success("token有效，可用");
        }
        return Ret.success("token已失效，不可用");
    }*/



    /*@ApiOperation(value = "使用Token登入",notes = "正确登入返回token")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token",value = "token",required = true,paramType = "query",dataType = "String"),
    })
    @RequestMapping(value="token/login",method = RequestMethod.POST)
    public String login(String token){
        String newToken = userService.tokenLogin(token,true,HttpUtil.getIp());

        if(null == newToken){
            return Ret.err("登入失败!");
        }
        return Ret.success("获取成功！",newToken);

    }*/

    @ApiOperation(value = "邮箱验证",notes = "邮箱验证")
    @RequestMapping(value="validate/email",method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public String checkEmailExist(@RequestBody String body) throws ParamsException {
        String email = getParam(body,"email");

        if(null != userService.getUserByEamil(email)){
            return Ret.success("This email has been registered");
        }
        return Ret.err("The account is not registered");
    }

    @ApiOperation(value = "邮箱验证",notes = "邮箱验证")
    @RequestMapping(value="validate/email/register",method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public String checkEmailExistRegister(@RequestBody String body) throws ParamsException {
        String email = getParam(body,"email");

        if(null != userService.getUserByEamil(email)){
            return Ret.err("This email has been registered");
        }
        return Ret.success("The account is not registered");
    }


    @ApiOperation(value = "发送验证码",notes = "发送验证码")
    @ApiResponses(value = {
            @ApiResponse(code = 200,message = "{\n\"Msg\":\"发送成功！\",\n\"Code\":200\n}")
    })
    @RequestMapping(value="send/code",method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public String getValidateCode(@RequestBody String body) throws ParamsException {
        String email = getParam(body,"email");
        VerityCode verityCode = new VerityCode();
        verityCode.setCode(String.valueOf(randomInt()));
        verityCode.setEmail(email);
        verityCode.setCreateBy("ValidateController->send/code");
        verityCode.setUpdateBy("ValidateController->send/code");
        verityCodeService.save(verityCode);
        return sendHtmlMail(verityCode.getEmail(),verityCode.getCode()+" is your verification code",codeHtml.replace("{validateCode}",verityCode.getCode()));
    }



    /**
     * 保存用户渠道
     * @param chl
     */
    private void saveUserAds(String chl,long uid){
        AdsRecord adsRecord = new AdsRecord();
        DicAds dicAds;
        if(!StringUtils.isEmpty(chl)){
            dicAds = commonService.getAdsByName(chl);
        }else {
            dicAds = commonService.getAdsById(0);
        }
        adsRecord.setAdsType(dicAds.getId());
        adsRecord.setUid(uid);
        adsRecord.setCreateBy(dicAds.getName());
        adsRecord.setUpdateBy(dicAds.getName());
        userService.saveAdsRecord(adsRecord);
        // 新用户注册送报告
        productService.updateReport(uid,config.getReportNumber(),"register give");
    }

    public String sendHtmlMail(String to ,String subject,String content){
        MimeMessage message = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(message,true);
            helper.setTo(to);
            helper.setFrom(fromEmail);
            helper.setSubject(subject);
            helper.setText(content,true);
            javaMailSender.send(message);
            return Ret.success("send success");
        } catch (MessagingException e) {
            log.error("发送静态邮件失败：",e);
            return Ret.success("send fail");
        }
    }



    private int randomInt(){
        Random random = new Random();
        int n = random.nextInt(999999);
        return n;

    }
}
